/****************************************************************************
*
*  ALi (Shanghai) Corporation, All Rights Reserved. 2003 Copyright (C)
*
*  File: win_multiview.c
*
*  Description: m/p
*              
*  History:
*      Date        		Author         	Version   	Comment
*      ====        		======      	=======   	=======
*  1.  2006.05.30  	Sunny Yin     	0.1.000   	Initial
*
****************************************************************************/
#include <types.h>
#include <osal/osal.h>

#include <hld/dis/vpo.h>
#include <hld/hld_dev.h>
#include <hld/dmx/dmx.h>

#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <api/libosd/osd_lib.h>
//#include <api/libpub29/lib_pub27.h>
#include "osdobjs_def.h"
//#include <api/libtsi/si_monitor.h>
#include "osd_config.h"
#include "string.id"
#include "images.id"
#include "key.h"

#include "win_com.h"
#include "win_multiview.h"
#include "control.h"
#include "win_multiview_password.h"
#include "win_signalstatus.h"
#include "menus_root.h"

#ifndef __MM_MULTIVEW_BUFFER_ADDR
#define __MM_MULTIVEW_BUFFER_ADDR __MM_PVR_VOB_BUFFER_ADDR
#define __MM_MULTIVEW_BUFFER_LEN  __MM_PVR_VOB_BUFFER_LEN
#endif
extern void ap_pid_change(BOOL need_chgch);
extern P_NODE playing_pnode;
/*******************************************************************************
* WINDOW's objects declaration
*******************************************************************************/
MATRIX_BOX_NODE mb_node_mv_name[MULTI_VIEW_COUNT];

CONTAINER	g_cnt_multiview;
MATRIX_BOX	g_mtb_mv_name;
BITMAP		g_bmp_mv_load;
BITMAP		g_bmp_mv_signal;
TEXT_FIELD g_bmp_mv_signal_txt;

static BOOL g_key_exit = FALSE;
static BOOL g_key_ok = FALSE;
UINT16*	str_mv_prog_name;
static UINT32 SystemTvMode=0;
static BOOL g_age_lock = FALSE;
static UINT32 lock_play = 0;
static BOOL pwd_open_state = FALSE;

static VACTION win_mv_mtb_keymap(POBJECT_HEAD obj, UINT32 key);
static PRESULT win_mv_ctn_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);
static PRESULT win_mv_mtb_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);
static VACTION win_com_con_keymap(POBJECT_HEAD obj, UINT32 key);


#define WSTL_TRANS_IDX			WSTL_TRANS_IX
#define MBX_SH_IDX				WSTL_BUTTON_POP_SH_HD//WSTL_TEXT_04
#define MBX_HL_IDX				WSTL_BUTTON_POP_HL_HD//WSTL_TEXT_08//??
#define IM_LOADING_02			IM_LOADING
#define IM_GROUP_LOCK			IM_INFORMATION_ICON_6_09//IM_LOCK//IM_NINE_LOCK
#define IM_SIGNAL_LEVEL_01	    IM_EPG_COLORBUTTON_BLUE//IM_ORANGE_ARROW_S//IM_NINE_NOSIGNAL
#define IM_GROUP_MONEY			IM_INFORMATION_ICON_MONEY//IM_NINE_MONEY

CONTAINER	g_cnt_multiview = {
									{	OT_CONTAINER, //object type
										C_ATTR_ACTIVE,   // defined in form C_ATTR_XXX
										C_FONT_DEFAULT,    // defined in form C_FONT_XXX
    										0,      // 0: for component without focus

										0,//UINT8 bLeftID;
										0,//UINT8 bRightID;
										0,//UINT8 bUpID;
										0,//UINT8 bDownID;

										{CNT_MV_L, CNT_MV_T, CNT_MV_W,CNT_MV_H},//OSD_RECT frame;
										{0,0,0,0},//COLOR_STYLE style;

										win_com_con_keymap,//PFN_KEY_MAP pfnKeyMap;
										(PFN_CALLBACK)win_mv_ctn_callback,//PFN_CALLBACK pfnCallback;

										NULL,//POBJECT_HEAD pNext;
										NULL//POBJECT_HEAD pRoot;
									},
									(POBJECT_HEAD)&g_mtb_mv_name,
									1,
									0
};


MATRIX_BOX	g_mtb_mv_name = {
									{	OT_MATRIXBOX, //object type
										C_ATTR_ACTIVE,   // defined in form C_ATTR_XXX
										C_FONT_DEFAULT,    // defined in form C_FONT_XXX
    										1,      // 0: for component without focus

										1,//UINT8 bLeftID;
										1,//UINT8 bRightID;
										1,//UINT8 bUpID;
										1,//UINT8 bDownID;

										{MTB_MV_L,MTB_MV_T,MTB_MV_W,MTB_MV_H},//COLOR_STYLE style;
//								{WSTL_BUTTON_POP_SH_HD,WSTL_BUTTON_01_HD,0,0},//COLOR_STYLE style;
										{MBX_SH_IDX,MBX_HL_IDX,0,0},//COLOR_STYLE style;
                                        
										win_mv_mtb_keymap,//PFN_KEY_MAP pfnKeyMap;
										win_mv_mtb_callback,//PFN_CALLBACK pfnCallback;

										(POBJECT_HEAD)&g_bmp_mv_signal_txt,//POBJECT_HEAD pNext;
										(POBJECT_HEAD)&g_cnt_multiview//POBJECT_HEAD pRoot;
										},
										MATRIX_ROW_WRAP,//UINT8 bStyle;
										MATRIX_TYPE_WCHAR,//UINT8 bCellType;
										MULTI_VIEW_COUNT,//INT16 nCount;
										mb_node_mv_name,//	PMATRIX_BOX_NODE pCellTable;

										MULTI_VIEW_X_COUNT,//INT16 nRow;
										(MULTI_VIEW_COUNT/MULTI_VIEW_X_COUNT),//INT16 nCol;
										C_ALIGN_CENTER | C_ALIGN_VCENTER,//    UINT8 bAlign;
										6,//INT8 bIntervalX;
										(TXT_MV_Y_SHIFT-MTB_MV_H),//INT8 bIntervalY;
										0,//INT8 bIntervalT;
										0,//INT8 bIntervalZ;
										0,//INT8 bIntervalT;
										0,//INT8 bIntervalZ;
										0//INT16 nPos;            // the item index of current position	
};

BITMAP	g_bmp_mv_load = {
									{	OT_BITMAP, //object type
										C_ATTR_ACTIVE,   // defined in form C_ATTR_XXX
										C_FONT_DEFAULT,    // defined in form C_FONT_XXX
    										0,      // 0: for component without focus

										0,//UINT8 bLeftID;
										0,//UINT8 bRightID;
										0,//UINT8 bUpID;
										0,//UINT8 bDownID;

										{BMP_LOAD_L, BMP_LOAD_T,BMP_LOAD_W,BMP_LOAD_H},//OSD_RECT frame;
										{WSTL_TRANS_IDX,0,0,0},//COLOR_STYLE style;

										NULL,//PFN_KEY_MAP pfnKeyMap;
										NULL,//PFN_CALLBACK pfnCallback;

										NULL,//POBJECT_HEAD pNext;
										NULL//POBJECT_HEAD pRoot;
										},
										 C_ALIGN_LEFT | C_ALIGN_VCENTER,//UINT8 bAlign;
										 0,//UINT8 bX;
										 0, //UINT8 bY;
										 IM_LOADING_02, //UINT16 wIconID;
};

BITMAP	g_bmp_mv_signal = {
									{	OT_BITMAP, //object type
										C_ATTR_ACTIVE,   // defined in form C_ATTR_XXX
										C_FONT_DEFAULT,    // defined in form C_FONT_XXX
    										0,      // 0: for component without focus

										0,//UINT8 bLeftID;
										0,//UINT8 bRightID;
										0,//UINT8 bUpID;
										0,//UINT8 bDownID;

										{BMP_SIG_L, BMP_SIG_T,BMP_SIG_W,BMP_SIG_H},//OSD_RECT frame;
										{WSTL_TRANS_IDX,0,0,0},//COLOR_STYLE style;

										NULL,//PFN_KEY_MAP pfnKeyMap;
										NULL,//PFN_CALLBACK pfnCallback;

										NULL,//POBJECT_HEAD pNext;
										NULL//POBJECT_HEAD pRoot;
										},
										 C_ALIGN_LEFT | C_ALIGN_VCENTER,//UINT8 bAlign;
										 0,//UINT8 bX;
										 0, //UINT8 bY;
										 IM_LOADING_02, //UINT16 wIconID;
};

#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,resID,str)	\
	DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    	0,0,0,0,0, l,t,w,h, WSTL_TEXT_10_HD, WSTL_TEXT_10_HD, WSTL_TEXT_10_HD,WSTL_TEXT_10_HD,   \
    	NULL, NULL,  \
    	C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,resID,str)
    	
LDEF_TXT(&g_cnt_multiview,g_bmp_mv_signal_txt,NULL, TXT_L, TXT_T,TXT_W, TXT_H, 0, 0);

static UINT16   g_mv_top, g_mv_total, g_mv_page_cnt;


static volatile UINT32 g_load_posi;
//b_lock default init=1,fixed live play lock program not need input pwd 
//when boot up or resume from standy
static BOOL b_lock=1;
static volatile BOOL check_prog_finised = 0;
static UINT32 mv_state = BOX_SCAN_START;
static struct MultiViewPara	mv_para;

BOOL win_multiview_get_lock(void)
{
    return b_lock;
}
void win_multiview_set_lock(BOOL flag)
{
    b_lock=flag;
}
void win_multiview_set_age_lock(BOOL age_lock)
{
    g_age_lock = age_lock;
}
BOOL win_multiview_get_age_lock(void)
{
    return g_age_lock;
}
BOOL win_multiview_get_state(void)
{
    return ((mv_state == BOX_SCAN_START)||!check_prog_finised ||((UIMultiviewGetStatus()&MV_SCAN_SCREEN)==MV_SCAN_SCREEN));
}

static PRESULT win_mv_message_proc(UINT32 msg_type, UINT32 msg_code);

/*******************************************************************************
* Function definition
*******************************************************************************/
#ifdef NEW_DEMO_FRAME
/* Get ft and dev list before enter mv */
static void win_mv_pre_enter(P_NODE *p_node, struct cc_es_info *es, struct ft_frontend *ft, struct cc_device_list *dev_list)
{
	struct cc_param param;
	BOOL ci;

	MEMSET(&param, 0, sizeof(struct cc_param));
	api_pre_play_channel(p_node, ft, &param, &ci, FALSE);
	MEMCPY(es, &(param.es), sizeof(struct cc_es_info));
	es->sim_onoff_enable = 0;
	MEMCPY(dev_list, &(param.dev_list), sizeof(struct cc_device_list));
}
#endif
static void MV_DPid_callback(UINT16 uIndex)
{
	P_NODE p_node;
#ifdef NEW_DEMO_FRAME
	struct ft_frontend frontend;
	struct cc_es_info es;
	struct cc_device_list dev_list;
#endif
	get_prog_at(mv_para.uProgInfo[uIndex], &p_node);
	win_mv_pre_enter(&p_node, &es, &frontend, &dev_list);
	MEMCPY(&(mv_para.mv_param[uIndex].es), &es, sizeof(struct cc_es_info));
	MEMCPY(&(mv_para.mv_param[uIndex].device_list), &dev_list, sizeof(struct cc_device_list));
	MEMCPY(&(mv_para.mv_param[uIndex].ft), &frontend, sizeof(struct ft_frontend));
	MV_Update_PlayPara(&mv_para);
}
static UINT32 win_mv_cb(UINT16 uIndex)
{
	BOOL bSendCmd;
	UINT32 timeout = 0;   

    check_prog_finised = 0;
    g_load_posi = uIndex;
    P_NODE p_node;
	get_prog_at(g_mv_top+(UINT8)uIndex, &p_node);
        
	do
	{ 
 		bSendCmd = ap_send_msg(CTRL_MSG_SUBTYPE_CMD_UPDATE_VIEW, uIndex, FALSE);   
 		if(!bSendCmd && !get_mv_exit())
		{
			osal_task_sleep(10);
 		}
	}while(!bSendCmd && !get_mv_exit());

    while(!check_prog_finised && !get_mv_exit()&&!(timeout>10)/*&& !get_mv_cancel()*/)
    {
        //soc_printf("wait\n");
        osal_task_sleep(10);
        if(!(pwd_open_state&&(sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))))
        timeout++;
    }
    
	if(b_lock/*|| get_mv_cancel()*/)
    {
        //libc_printf("[%s]:b_lock:%d\n",__FUNCTION__,b_lock);
        return BOX_PLAY_ABORT;
    }
    else
    {
        //libc_printf("[%s]:b_lock:%d\n",__FUNCTION__,b_lock);
        return BOX_PLAY_NORMAL;
    }
}

static void win_mv_load_page(UINT16 first_idx, UINT32 page_cnt)
{
	UINT32				i,j;
	UINT16			width, height;
	struct MVInitPara 	tMvInitPara;
	UINT16			tmp_name[MAX_DISP_STR_LEN];
	UINT8				tmp_idx[10];
	//struct MultiViewPara	mv_para;
	P_NODE p_node;
	
#ifdef NEW_DEMO_FRAME
	struct ft_frontend frontend;
	struct cc_es_info es;
	struct cc_device_list dev_list;
#endif
	//height = (TV_MODE_PAL == tv_mode) ? MV_VIDEO_HEIGHT_P : MV_VIDEO_HEIGHT_N;
    UINT8 tv_mode;
    UINT32 pipmode=0;
    tv_mode = api_video_get_tvout();

    if(TV_MODE_720P_50 == tv_mode || TV_MODE_1080I_25 == tv_mode 
        || TV_MODE_576P == tv_mode || TV_MODE_PAL == tv_mode 
        || TV_MODE_1080P_25 == tv_mode || TV_MODE_1080P_50 == tv_mode 
        || TV_MODE_1080P_24 == tv_mode 
        || TV_MODE_PAL_N == tv_mode)
	{
    	pipmode = 576*5;
    }
    else if(TV_MODE_720P_60 == tv_mode || TV_MODE_480P == tv_mode
        || TV_MODE_1080I_30 == tv_mode || TV_MODE_NTSC358 == tv_mode
        || TV_MODE_1080P_30 == tv_mode || TV_MODE_1080P_60 == tv_mode 
        || TV_MODE_NTSC443 == tv_mode|| TV_MODE_PAL_M == tv_mode )
    {
        pipmode = 480*6;
    }        


	
	mv_para.uBoxNum = page_cnt;
	mv_para.uBoxActiveIdx = OSD_GetMtrxboxCurPos(&g_mtb_mv_name) + 1;
    mv_para.MVMode = MV_9_BOX;
	mv_para.multi_view_buf_addr= __MM_MULTIVEW_BUFFER_ADDR;
	mv_para.multi_view_buf_size = __MM_MULTIVEW_BUFFER_LEN;
	
	width = TXT_MV_X_SHIFT;//MV_VIDEO_WIDTH ;//+ MV_VIDEO_WIDTH % 16;
	height = TXT_MV_Y_SHIFT;//MV_VIDEO_HEIGHT;// + MTB_MV_H * OSD_MULTI_HEIGHT/576;
	//height = height - height % 2; CNT_MV_L+ TXT_MV_X_SHIFT * i
	
	for(i = 0;  i<page_cnt; i++)
	{
		tMvInitPara.puBoxPosi[i].uX = MV_VIDEO_LEFT*3/2 + (i%MULTI_VIEW_X_COUNT) * width*3/2;
		tMvInitPara.puBoxPosi[i].uY = MV_VIDEO_TOP*3/2 + (i/MULTI_VIEW_X_COUNT) * height*3/2;
        //
		tMvInitPara.tMPipBoxPosi[i].uX = MV_VIDEO_LEFT*9/16 + (i%MULTI_VIEW_X_COUNT) * width*9/16;
		tMvInitPara.tMPipBoxPosi[i].uY = MV_VIDEO_TOP*pipmode/720 + (i/MULTI_VIEW_X_COUNT) * height*pipmode/720;
		
#ifdef BIDIRECTIONAL_OSD_STYLE
	    if (OSD_GetMirrorFlag() == TRUE)
	    {
		    tMvInitPara.puBoxPosi[i].uX = 1280*3/2 - tMvInitPara.puBoxPosi[i].uX - width*3/2;
		    tMvInitPara.tMPipBoxPosi[i].uX = 1280*9/16 - tMvInitPara.tMPipBoxPosi[i].uX - width*9/16;
		    
		}   
#endif 
		sprintf(tmp_idx, "%d-",first_idx+i+1);
		ComAscStr2Uni(tmp_idx, (UINT16*)mb_node_mv_name[i].str);
		//api_get_channel_name(first_idx+i, tmp_name);
		get_prog_at(first_idx+i,&p_node);
		if(p_node.ca_mode)
		{
			SetUniStrCharAt(tmp_name,'$',0);
			j = 1;
		}
		else
			j = 0;
		ComUniStrCopyChar((UINT8*)&tmp_name[j],p_node.service_name);			
		
		mv_para.uProgInfo[i] = first_idx+i;
		win_mv_pre_enter(&p_node, &es, &frontend, &dev_list);
		MEMCPY(&(mv_para.mv_param[i].es), &es, sizeof(struct cc_es_info));
		MEMCPY(&(mv_para.mv_param[i].device_list), &dev_list, sizeof(struct cc_device_list));
		MEMCPY(&(mv_para.mv_param[i].ft), &frontend, sizeof(struct ft_frontend));
		ComUniStrCat((UINT16*)mb_node_mv_name[i].str, (const UINT16*)tmp_name);
	}

	//if(TV_MODE_PAL == tv_mode)
	//{
	tMvInitPara.tMpSize.uWidth=MV_MP_WIDTH*3/2;
	tMvInitPara.tMpSize.uHeight=MV_MP_HEIGHT*3/2;

	tMvInitPara.tPipSize.uWidth=MV_VIDEO_WIDTH*3/2;//MV_VIDEO_WIDTH*3/2;
	tMvInitPara.tPipSize.uHeight=MV_VIDEO_HEIGHT*3/2;//MV_VIDEO_HEIGHT*3/2;	

	tMvInitPara.tMPipSize.uWidth=MV_VIDEO_WIDTH*9/16+1;
	tMvInitPara.tMPipSize.uHeight=MV_VIDEO_HEIGHT*pipmode/720+20;
	//}
	//else
	//{
	//	tMvInitPara.tMpSize.uHeight=480;
	//	tMvInitPara.tPipSize.uHeight=height-24;	
	//}
	
	tMvInitPara.callback=	win_mv_cb;
	tMvInitPara.AVcallback=MV_DPid_callback;
	tMvInitPara.uBoxNum= page_cnt;

	UIMultiviewInit(&tMvInitPara,MV_9_BOX);
	UIMultiviewEnter(&mv_para);
}

/*********************************************************************************
*
*	Window handle's open,proc and handle
*
**********************************************************************************/
static void win_mv_scale_screen()
{
	struct OSDRect 	multi_full_rect;
	enum	OSDSys	eOSDSys;
	struct OSDRect	r;
	UINT8	i;
	UINT8 tv_mode;
	enum TVSystem tvsys;
	struct OSDPara	tOpenPara;
	struct OSDRect tOpenRect;

	OSD_GetRectOnScreen(&r);
	r.uLeft= r.uTop= 0;       
	OSD_DrawFrame(&r, OSD_TRANSPARENT_COLOR, NULL);
	
	multi_full_rect.uTop =	0;//OSD_MULTI_TOP;
	multi_full_rect.uLeft = 0;//OSD_MULTI_LEFT;
	multi_full_rect.uWidth = 1280;//OSD_MULTI_WIDTH;
	multi_full_rect.uHeight = 720;//OSD_MULTI_HEIGHT;
	OSD_SetRectOnScreen(&multi_full_rect);
	
	//reset OSD rect and scale
//	tv_mode = api_video_get_tvout();//sys_data_get_tv_mode();
//	if(TV_MODE_PAL == tv_mode)
//		eOSDSys = OSD_PAL;
//	else
//		eOSDSys = OSD_NTSC;
//	OSD_Scale(OSD_VSCALE_DVIEW, (UINT32)&eOSDSys);			
    

	OSD_DrawFill(CNT_MV_L, CNT_MV_T, TXT_MV_X_SHIFT*MULTI_VIEW_X_COUNT+6, 4, 0xffff, NULL);
	OSD_DrawFill(CNT_MV_L, CNT_MV_T+4, 6,TXT_MV_Y_SHIFT*MULTI_VIEW_X_COUNT+4, 0xffff, NULL);
	for(i = 1 ; i <= MULTI_VIEW_X_COUNT; i++)
	{
		OSD_DrawFill(CNT_MV_L,CNT_MV_T+4+TXT_MV_Y_SHIFT * i,TXT_MV_X_SHIFT*MULTI_VIEW_X_COUNT, 4, 0xffff, NULL);
		OSD_DrawFill(CNT_MV_L+ TXT_MV_X_SHIFT * i , CNT_MV_T+4, 6, TXT_MV_Y_SHIFT*MULTI_VIEW_X_COUNT+4, 0xffff, NULL);
	}
}

static BOOL Enter_MV_mode = FALSE;
static BOOL win_mv_page_shift(UINT16 start, UINT16 count, INT16 shift)
{
	INT16	first_channel = start;
	struct OSDRect	r;
	if((count < shift) ||(count < (0-shift)))
		return FALSE;
	else
	{
		first_channel += shift;

		if(first_channel < 0) 
		{
			if(0 == start)
				first_channel= count - g_mv_page_cnt;
			else
				first_channel= 0;
		}
		else if(first_channel >= count)
		{
			if((count - g_mv_page_cnt) == start)
				first_channel = 0;
			else 
				first_channel= count - g_mv_page_cnt;
		}
		else if((first_channel + g_mv_page_cnt >=  count) && (count > g_mv_page_cnt))
		{//when channels after first one is no more than 9
		    if(Enter_MV_mode)
		    {
		        Enter_MV_mode = FALSE;
			    OSD_SetMtrxboxCurPos(&g_mtb_mv_name, (first_channel + g_mv_page_cnt - count));
			}
			first_channel = count - g_mv_page_cnt;
		}
	}
	g_mv_top = first_channel;

	win_mv_load_page(first_channel, g_mv_page_cnt);
	
}


static void win_mv_init()
{
	SystemTvMode=sys_data_get_aspect_mode();
	if(TV_ASPECT_RATIO_169==SystemTvMode)
	{
		//MV_DEBUG("%s-->TvMode=%d\n",__FUNCTION__,SystemTvMode);
		vpo_aspect_mode( (struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 0), TV_4_3, NORMAL_SCALE);
	}
	UINT16	i;
	UINT16	cur_channel;

	if(GetPauseState())
			SetPauseOnOff();
	
	//alloc string
	for(i = 0; i < MULTI_VIEW_COUNT; i++)
	{
		mb_node_mv_name[i].str = (UINT32)display_strs[i];//(UINT32)api_alloc_static_str(API_STATIC_STR_LEN);
		mb_node_mv_name[i].num = 0;
		mb_node_mv_name[i].bAttr = C_ATTR_ACTIVE;
	}
	
	//init parametre
	g_mv_total =get_prog_num(VIEW_ALL | TV_CHAN, 0);;//get_node_num(TYPE_PROG_NODE, NULL);
	cur_channel = sys_data_get_cur_group_cur_mode_channel();

	if(g_mv_total <= MULTI_VIEW_COUNT)
	{
		g_mv_top = 0;
		OSD_SetMtrxboxCount(&g_mtb_mv_name, g_mv_total, MULTI_VIEW_X_COUNT, MULTI_VIEW_X_COUNT);
		OSD_SetMtrxboxCurPos(&g_mtb_mv_name, cur_channel);
		g_mv_page_cnt = g_mv_total;
	}
	else
	{
		g_mv_top = cur_channel;
		g_mv_page_cnt = MULTI_VIEW_COUNT;
		OSD_SetMtrxboxCount(&g_mtb_mv_name, g_mv_page_cnt, MULTI_VIEW_X_COUNT, MULTI_VIEW_X_COUNT);
		OSD_SetMtrxboxCurPos(&g_mtb_mv_name, 0);
	}
}


static void win_mv_update_signal(BOOL onoff,UINT16 idx)
{
	short	x, y;
	P_NODE	p_node;
	signal_lock_status lock_flag;
	signal_scramble_status scramble_flag;
	signal_lnbshort_status lnbshort_flag;
	signal_parentlock_status parrentlock_flag;
	struct ft_frontend frontend;
	struct cc_param chchg_param;
    BOOL ci_start_service = FALSE;
	BOOL b_force=0;
	
	//GetSignalStatus(&lock_flag, &scramble_flag,&lnbshort_flag,&parrentlock_flag,&ratinglock_flag); 
#ifdef PARENTAL_SUPPORT
    signal_ratinglock_status ratinglock_flag;
    GetSignalStatus(&lock_flag, &scramble_flag,&lnbshort_flag,&parrentlock_flag,&ratinglock_flag);
#else
    GetSignalStatus(&lock_flag,&scramble_flag,&lnbshort_flag,&parrentlock_flag);
#endif
	get_prog_at(g_mv_top+idx, &p_node);

    if((b_lock)&& onoff)
	{
		OSD_SetBitmapContent(&g_bmp_mv_signal, IM_GROUP_LOCK);
		OSD_SetTextFieldContent(&g_bmp_mv_signal_txt, STRING_ID,RS_SYSTME_PARENTAL_LOCK);
	}
	else if((SIGNAL_STATUS_UNLOCK == lock_flag)&& onoff)
	{
		OSD_SetBitmapContent(&g_bmp_mv_signal, IM_SIGNAL_LEVEL_01);	
		OSD_SetTextFieldContent(&g_bmp_mv_signal_txt, STRING_ID, RS_MSG_NO_SIGNAL);
	}
	else if((((p_node.ca_mode == 1)&&(MV_SCAN_SCREEN & UIMultiviewGetStatus()))||(SIGNAL_STATUS_SCRAMBLED == scramble_flag))&& onoff)
	{
		OSD_SetBitmapContent(&g_bmp_mv_signal, IM_GROUP_MONEY);	
		OSD_SetTextFieldContent(&g_bmp_mv_signal_txt, STRING_ID, RS_SYSTME_CHANNEL_SCRAMBLED);
	}
	else
	{
		OSD_SetBitmapContent(&g_bmp_mv_signal, 0);
		OSD_SetTextFieldContent(&g_bmp_mv_signal_txt, STRING_ID, 0);
	}

	x = BMP_SIG_L + ((idx)%MULTI_VIEW_X_COUNT * TXT_MV_X_SHIFT);
	y = BMP_SIG_T + ((idx)/MULTI_VIEW_X_COUNT* TXT_MV_Y_SHIFT) ;
	OSD_MoveObject((POBJECT_HEAD)&g_bmp_mv_signal, x, y, FALSE);
	OSD_MoveObject((POBJECT_HEAD)&g_bmp_mv_signal_txt, x-(TXT_W-BMP_SIG_W)/2, y+BMP_SIG_H, FALSE);
	
	OSD_DrawObject((POBJECT_HEAD)&g_bmp_mv_signal, C_UPDATE_ALL);
	OSD_DrawObject((POBJECT_HEAD)&g_bmp_mv_signal_txt, C_UPDATE_ALL);
	
}

static void win_mv_load_sign_onoff(BOOL onoff, UINT16 idx)
{
	short	x, y;
	
	x = BMP_LOAD_L + ((idx)%MULTI_VIEW_X_COUNT * TXT_MV_X_SHIFT);
	y = BMP_LOAD_T + ((idx)/MULTI_VIEW_X_COUNT* TXT_MV_Y_SHIFT) ;
	OSD_MoveObject((POBJECT_HEAD)&g_bmp_mv_load, x, y, FALSE);
    
	if(onoff)
		OSD_DrawObject((POBJECT_HEAD)&g_bmp_mv_load, C_UPDATE_ALL);
	else
	{
		OSD_HideObject((POBJECT_HEAD)&g_bmp_mv_load, 0);
		win_mv_update_signal(FALSE,idx);
	}

}

static VACTION win_mv_mtb_keymap(POBJECT_HEAD obj, UINT32 key)
{
	VACTION	act = VACT_PASS;

	switch(key)
	{
		case V_KEY_P_UP:
			act = VACT_CURSOR_PGUP;
			break;
		case V_KEY_P_DOWN:
			act = VACT_CURSOR_PGDN;
			break;
		//case V_KEY_MUTE:
		case V_KEY_V_UP:
		case V_KEY_V_DOWN:
			act = VACT_NO_RESPOND;
			break;
		default:
			act = OSD_MatrixboxKeyMap(obj, key);
			break;
	}
	
	return act;
}

static UINT32 chg_time_out = 0;

static PRESULT win_mv_mtb_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	UINT32 i;
	static UINT32	exit_key[] = 
			{
				V_KEY_UP, V_KEY_DOWN, 
				V_KEY_C_UP, V_KEY_C_DOWN, 
				//V_KEY_P_UP, V_KEY_P_DOWN, 
				V_KEY_LEFT,V_KEY_RIGHT,
				V_KEY_MENU,V_KEY_EXIT
			};
	switch(event)
	{
		case EVN_UNKNOWN_ACTION:
		{
			VACTION vact = (VACTION)(param1>>16);
			if((VACT_CURSOR_PGUP == vact) || (VACT_CURSOR_PGDN == vact))
			{
				INT16 shift =(VACT_CURSOR_PGUP == vact) ? (0-MULTI_VIEW_COUNT) : MULTI_VIEW_COUNT ;
				win_mv_page_shift(g_mv_top,g_mv_total, shift );	
				OSD_TrackObject(pObj, C_UPDATE_ALL);
				sys_data_set_cur_group_channel(g_mv_top+OSD_GetMtrxboxCurPos(&g_mtb_mv_name));
			}
			else if(VACT_ENTER == vact)
			{
				return PROC_LEAVE;
			}
			else if(VACT_NO_RESPOND == (UINT8)vact)
				return PROC_LOOP;
			break;
		}
		case EVN_ITEM_PRE_CHANGE:
		{
			UINT8		multi_status = UIMultiviewGetStatus();
			if((MV_SCAN_SCREEN & multi_status))// || !check_prog_finised || MV_IDLE &multi_status)
				return PROC_LOOP;
            SetBoxPlayStatus(FALSE);
			chg_time_out = 0;
			win_multiview_set_age_lock(FALSE);
            lock_play = 0;
			break;
		}
		case EVN_ITEM_POST_CHANGE:
		{
			UINT16	cur_channel = g_mv_top+param1;
			UINT8		multi_status = UIMultiviewGetStatus();
			check_prog_finised = 0;
			b_lock = FALSE;
			if(MV_SCAN_SCREEN & multi_status)
				return PROC_LOOP;
			else
			{
                BOOL age_check;
                P_NODE p_node;
                SYSTEM_DATA* p_sys_data = sys_data_get();
			    get_prog_at(cur_channel, &p_node);
                MEMCPY(&playing_pnode, &p_node, sizeof(P_NODE));
			    age_check = FALSE;

    			UIMultiviewDrawOneBox(param1);
    			sys_data_set_cur_group_channel(cur_channel);
    			key_pan_display_channel(cur_channel);

    			if((sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))|| age_check)	
    			{
                    g_key_ok = FALSE;
                    pwd_open_state = TRUE;
    				if(win_mv_pwd_open(exit_key, (sizeof(exit_key)/sizeof(UINT32)) ) )
    				{
    					b_lock = FALSE;
    					g_key_ok = TRUE;
    					SetChannelParrentLock(SIGNAL_STATUS_PARENT_UNLOCK);
    			        check_prog_finised = 1;
    			        
    				}
    				else
    				{
    				    g_key_ok = FALSE;
    				    b_lock = TRUE;
    				    SetChannelParrentLock(SIGNAL_STATUS_PARENT_LOCK);
    				    check_prog_finised = 1;
    				}    				
    				win_mv_load_sign_onoff(0, param1);
    				win_mv_update_signal(TRUE,param1);
    			}	
    			pwd_open_state = FALSE;
			}
			break;
		}
		case EVN_UNKNOWNKEY_GOT:
		{
			break;
		}
		default:
			break;
	}
	
	return PROC_PASS;
}


static VACTION win_com_con_keymap(POBJECT_HEAD obj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
    case V_KEY_YELLOW:
	case V_KEY_EXIT:
	case V_KEY_MENU:
		act = VACT_CLOSE;
		break;		
	default:	
		act = OSD_ContainerKeyMap(obj,key);
	}

	return act;
}


extern UINT8 show_and_playchannel;
static PRESULT win_mv_ctn_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	UINT8 tv_mode;
	struct OSDRect	rect;
	UINT16	i;
	UINT16	channel;
	enum	OSDSys	eOSDSys;
	P_NODE p_node;
	SYSTEM_DATA* sys_data=sys_data_get();

#ifdef _INVW_JUICE   
int inviewCode, retCode;
#endif
	switch(event)
	{
	case EVN_PRE_OPEN:
#ifdef _INVW_JUICE   

if (INVIEW_isAppPaused() == FALSE) 
{ 
retCode = inviewCodeMap(V_KEY_ENTER, &inviewCode); 
INVIEW_pause(FALSE, inviewCode); 
} 
#endif 
		if(RADIO_CHAN== sys_data_get_cur_chan_mode())
		{
			ret = PROC_LEAVE;
			break;
		}
		g_key_exit = FALSE; 
        b_lock = FALSE; 
        win_multiview_ext_set_lock(FALSE);
        Enter_MV_mode = TRUE;
        SetBoxPlayStatus(FALSE);
		api_osd_mode_change(OSD_NO_SHOW);
		//sys_data_set_palette(1);
#ifdef PARENTAL_SUPPORT		
		clear_pre_ratinglock();
#endif		
	    system_state = SYS_STATE_9PIC;
        set_is_multiview_play(TRUE);
		api_stop_play(0);
#ifdef DVR_PVR_SUPPORT//DVR_PVR_SUPPORT
//		if(pvr_info.tms_r_handle != 0)
//			api_pvr_tms_proc(FALSE);
#endif
		win_mv_init();
		win_mv_page_shift(g_mv_top,g_mv_total, 0 );
		break;
	case EVN_PRE_DRAW:
		win_mv_scale_screen();
		break;
	case EVN_PRE_CLOSE:
		system_state = SYS_STATE_NORMAL;
		lock_play = 0;

        for(i=0;i<g_mv_page_cnt;i++)
        {
            win_mv_load_sign_onoff(0,i);     
        }
        
        ap_multiview_osd_switch( FALSE );
        
#if 0
		if(TV_MODE_PAL == tv_mode)
			eOSDSys = OSD_PAL;
		else
			eOSDSys = OSD_NTSC;
#endif
		UIMultiviewExit();
		OSD_GetRectOnScreen(&rect);
		rect.uLeft = 0;
		rect.uTop = 0;
		OSD_DrawFrame(&rect, OSD_TRANSPARENT_COLOR, NULL);
		
		rect.uLeft = ((1280 - 1008)>>1);//OSD_STARTCOL;
		rect.uTop =	(TV_MODE_PAL == tv_mode)  ? OSD_STARTROW_P : OSD_STARTROW_N ;
		rect.uWidth = 1008;//608;
		rect.uHeight = 640;//430;
		
		eOSDSys = OSD_PAL;
		OSD_SetRectOnScreen(&rect);
		//OSD_Scale(OSD_VSCALE_OFF, (UINT32)&eOSDSys);
#ifdef PARENTAL_SUPPORT
        clear_pre_ratinglock();
#endif        
		si_monitor_register((on_pid_change_t)ap_pid_change);	

		if(NULL != (UINT32*)param2)
		{
			UINT32*	evn = (UINT32*)param2;
			*evn &= (!C_CLOSE_CLRBACK_FLG);
		}
		//UIChChgStopProg(TRUE);
		break;
    case EVN_POST_CLOSE:
		g_key_exit = FALSE; 
        SetBoxPlayStatus(FALSE);
#if (TTX_ON ==1)
#ifdef _SUPPORT_64M_MEM
//64M project Multiview share with PVR/TTX/EPG/SUBTITLE/AD
//Exit Multiview should init subpage,only call this in single CPU
        init_SubPageCB();
#endif
#endif        
        set_is_multiview_play(FALSE);
		if(TV_ASPECT_RATIO_169==SystemTvMode)
		{
			win_av_set_ratio(sys_data,3);
			sys_data_set_display_mode(&(sys_data->avset));	
		}
        sys_data_set_palette(1);
#ifdef _INVW_JUICE   
			ap_send_msg(CTRL_MSG_SUBTYPE_CMD_ENTER_ROOT, (UINT32)CHANNEL_BAR_HANDLE, FALSE);

#ifdef DISABLE_ALI_INFORBAR
		            retCode = inviewCodeMap(V_KEY_ENTER, &inviewCode);

					INVIEW_resume(inviewCode);

					INVIEW_handleIR(inviewCode);
					//proc_ret = PROC_PASS;


					
#endif


#else
	{
		channel = sys_data_get_cur_group_cur_mode_channel();
		show_and_playchannel = 0;
		ap_send_msg(CTRL_MSG_SUBTYPE_CMD_ENTER_ROOT, (POBJECT_HEAD)&g_win_progname, FALSE);
		api_play_channel(channel, TRUE, TRUE,FALSE);
	}
#endif
        //b_lock = FALSE; 
		break;
	case EVN_MSG_GOT:
		ret =  win_mv_message_proc(param1,param2);
		break;
	default:
		;
	}
	
	return ret;
}
static PRESULT win_mv_message_proc(UINT32 msg_type, UINT32 msg_code)
{
	PRESULT ret = PROC_LOOP;

	UINT8		focus = (UINT8)msg_code;
	UINT8		multi_status;
	UINT16		cur_posi;
	BOOL		load_status;
	P_NODE p_node;
	BOOL	age_check = FALSE;
	SYSTEM_DATA* p_sys_data;
	UINT32 i;
    UINT32 uChannelIndex;
    
	static UINT32	exit_key[] = 
			{
				V_KEY_UP, V_KEY_DOWN, 
				V_KEY_C_UP, V_KEY_C_DOWN, 
				//V_KEY_P_UP, V_KEY_P_DOWN, 
				V_KEY_LEFT,V_KEY_RIGHT,
				V_KEY_MENU,V_KEY_EXIT
			};

	p_sys_data = sys_data_get();
	multi_status = UIMultiviewGetStatus();

    signal_lock_status lock_flag;
    signal_scramble_status scramble_flag;
    signal_lnbshort_status lnbshort_flag;
    signal_parentlock_status parrentlock_flag;
        	
#ifdef PARENTAL_SUPPORT
    signal_ratinglock_status ratinglock_flag;
    GetSignalStatus(&lock_flag, &scramble_flag,&lnbshort_flag,&parrentlock_flag,&ratinglock_flag);
#else
    GetSignalStatus(&lock_flag,&scramble_flag,&lnbshort_flag,&parrentlock_flag);
#endif
        
	switch(msg_type)
	{
	case CTRL_MSG_SUBTYPE_CMD_UPDATE_VIEW:
 		focus = (UINT8)msg_code;
        load_status = !(msg_code&BOX_FINISHED);	

        if(msg_code & BOX_SCAN_START)
        {
        	for(i=0;i<g_mv_page_cnt;i++)
                win_mv_load_sign_onoff(0,i);
            check_prog_finised = 1;
            mv_state = BOX_SCAN_START;
        }
        else if(load_status)
        {
			//key_set_signal_check_flag(SIGNAL_CHECK_RESET);
			get_prog_at(focus + g_mv_top, &p_node);
#ifdef AGE_LIMIT_FEATURE

            //SYSTEM_DATA*	p_sys_data = sys_data_get();
            age_check = FALSE;
    		if(p_sys_data->rating_sel)
    		{
    			if(rating_check(focus + g_mv_top,1))
    			{
    					age_check = TRUE;
    			}
    		}
#endif
			if((sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))|| age_check)
			{					
				if((MV_SCAN_SCREEN & multi_status) && g_mv_page_cnt!= 1)
					b_lock = TRUE;
			}
			else
				b_lock = FALSE;
				
			win_mv_load_sign_onoff(load_status, focus);
            check_prog_finised = 1;
            mv_state = BOX_SCAN_START;
        }
    	else if(msg_code & BOX_FOCUS)//load finish or other circumstance
    	{
    		get_prog_at(focus + g_mv_top, &p_node);
    		win_mv_load_sign_onoff(0, focus);
    		if((p_node.lock_flag || p_node.provider_lock))
    		{
    			UIMultiviewDrawOneBox(focus);
    			sys_data_set_cur_group_channel(focus + g_mv_top);
    			key_pan_display_channel(focus + g_mv_top);
    			 
    		}
            if(msg_code & BOX_FINISHED)
            {
                b_lock = FALSE;
            #ifdef PARENTAL_SUPPORT		
        		clear_pre_ratinglock();
            #endif		
            }
    		check_prog_finised = 1;
    		mv_state = BOX_FINISHED;
    	} 
    	else if(msg_code & BOX_FINISHED)
    	{
    	    if((MV_SCAN_SCREEN & multi_status)||(MV_ACTIVE & multi_status))
    	    {

                P_NODE p_node;
                SYSTEM_DATA* p_sys_data = sys_data_get();
			    get_prog_at(focus + g_mv_top, &p_node);
    			if((sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))&&!g_key_ok)
                    b_lock = TRUE;    
    			win_mv_update_signal(TRUE,focus);
    	    }
            check_prog_finised = 1;
            mv_state = BOX_FINISHED;

    	}
    	else
    	{
    			win_mv_load_sign_onoff(load_status, focus);
    			if(MV_SCAN_SCREEN & multi_status)
    			    win_mv_update_signal(TRUE,focus); 
    			check_prog_finised = 1;  
    			mv_state = BOX_FINISHED;
    	}
        
		break;
    case CTRL_MSG_SUBTYPE_STATUS_SIGNAL:
        if( !(MV_SCAN_SCREEN & multi_status))
        {
            //osal_task_sleep(1);
            chg_time_out++;
        }
        load_status = !(g_load_posi& BOX_FINISHED);        
        if( !(MV_SCAN_SCREEN & multi_status) && !load_status && check_prog_finised && (chg_time_out >= 1))
        { 
            chg_time_out = 0;
            P_NODE p_node;
            SYSTEM_DATA* p_sys_data = sys_data_get();
			focus = OSD_GetMtrxboxCurPos(&g_mtb_mv_name);
			get_prog_at(focus + g_mv_top, &p_node);
            if(GetBoxPlayStatus())
                win_mv_update_signal(TRUE,focus);
#ifdef AGE_LIMIT_FEATURE
    		if((p_sys_data->rating_sel)||(p_node.lock_flag))
    		{
    			if(win_multiview_get_age_lock())
    			{
    					age_check = TRUE;
    					b_lock = TRUE;
                        if(GetBoxPlayStatus())
                            win_mv_update_signal(TRUE,focus);
    			}
    			else if((sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))&&!g_key_ok)
    			{
                    b_lock = TRUE;  
                    if(GetBoxPlayStatus())
                        win_mv_update_signal(TRUE,focus);
    			}
    			else
    			{
    			    age_check = FALSE;
    			    b_lock = FALSE;
    			}
    		}

            if(age_check && lock_play != 1)
            {
                //UIChChgLockProg(focus + g_mv_top, 0);
                lock_play = 1;
            }
            else if(!age_check && (lock_play != 2)&& (lock_play != 0))
            {
                lock_play = 2;
                UIMultiviewDrawOneBox(focus);
                win_multiview_set_age_lock(FALSE);
            }
#else
            if((sys_data_get_channel_lock() && (p_node.lock_flag || p_node.provider_lock))&&!g_key_ok)
                b_lock = TRUE; 
            if(GetBoxPlayStatus())
                win_mv_update_signal(TRUE,focus);
#endif
        }
        break;        
    case CTRL_MSG_SUBTYPE_CMD_AUDIO_PIDCHANGE:
    case CTRL_MSG_SUBTYPE_CMD_PIDCHANGE:
        //soc_printf("CTRL_MSG_SUBTYPE_CMD_PIDCHANGE\n");
        load_status = !(g_load_posi& BOX_FINISHED);        
        if( !(MV_SCAN_SCREEN & multi_status) && !load_status && check_prog_finised)
        {
			focus = OSD_GetMtrxboxCurPos(&g_mtb_mv_name);
			uChannelIndex = g_mv_top + focus;
			//soc_printf("uChannelIndex=%d\n",uChannelIndex);
			if(get_prog_at(uChannelIndex,&p_node) == SUCCESS && !b_lock)
			{       
				//soc_printf("play channel\n");
				//api_play_channel(uChannelIndex, TRUE, !b_lock, FALSE);
				UIMultiviewDrawOneBox(focus);

				//cc_stop_channel(0,0);
				//cc_play_channel(p_node.prog_id, 0);
			}            
        }
        else if( !(MV_SCAN_SCREEN & multi_status) && !b_lock)
        {
            //soc_printf("Resend CTRL_MSG_SUBTYPE_CMD_PIDCHANGE\n");
            ap_send_msg(CTRL_MSG_SUBTYPE_CMD_PIDCHANGE, msg_code,FALSE);
        }
        break;
        
	case CTRL_MSG_SUBTYPE_CMD_AGE_LIMIT_UPDATED:
	default:
		ret = PROC_PASS;
	}

	return ret;
}


